package com.wnxy.sddfp.trade.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wnxy.sddfp.client.bank.api.TradeLogApi;
import com.wnxy.sddfp.client.system.UserApi;
import com.wnxy.sddfp.common.model.dto.trade.BorrowRecordDTO;
import com.wnxy.sddfp.common.model.exception.Assert;
import com.wnxy.sddfp.common.model.query.BorrowRecordQuery;
import com.wnxy.sddfp.common.model.query.Pages;
import com.wnxy.sddfp.common.model.result.BaseResult;
import com.wnxy.sddfp.common.model.result.Result;
import com.wnxy.sddfp.common.model.result.enums.impl.ResultCode;
import com.wnxy.sddfp.common.model.vo.BorrowRecordVo;
import com.wnxy.sddfp.common.model.vo.BorrowSyncRecordVo;
import com.wnxy.sddfp.common.model.vo.UserInfoVo;
import com.wnxy.sddfp.trade.entity.BorrowRecord;
import com.wnxy.sddfp.trade.mapper.BorrowRecordMapper;
import com.wnxy.sddfp.trade.service.IBorrowRecordService;
import com.wnxy.sddfp.trade.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author yellow Docter
 * @date 2023 -07-31
 * @desc Primary可以理解为默认优先选择, 同时不可以同时设置多个,
 * 内部实质是设置BeanDefinition的primary属性
 */
@Slf4j
@Service
public class IBorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements IBorrowRecordService {
    // 注入feign客户端接口代理对象
    @Autowired
    private UserApi userApi;
    @Autowired
    TradeLogApi tradeLogApi;

    @Override
    public String verifyStatus(Integer approveStatus, Long borrowRecordId) {
        // 正常的需要token  校验接口
        // 01 生成流水号 更新借款记录
        String reqCode = "REQ_" + UUID.randomUUID().toString().substring(0, 12);
        // 查询 借款记录
        BorrowRecord borrowRecord = getById(borrowRecordId);
        // 设置流水
        borrowRecord.setReqCode(reqCode);
        // 更新
        updateById(borrowRecord);

        // 02 调用托管服务   需要远程调用
        BorrowSyncRecordVo borrowSyncRecordVo = new BorrowSyncRecordVo();
        // 发送远程数据
        borrowSyncRecordVo.setReqCode(borrowRecord.getReqCode());
        borrowSyncRecordVo.setAmount(borrowRecord.getAmount());
        borrowSyncRecordVo.setId(borrowRecord.getId());
        borrowSyncRecordVo.setName(borrowRecord.getName());
        borrowSyncRecordVo.setPeriod(borrowRecord.getPeriod());
        borrowSyncRecordVo.setUserCode(borrowRecord.getUserCode());
        borrowSyncRecordVo.setUserId(borrowRecord.getUserId());
        borrowSyncRecordVo.setBorrowRecordNo(borrowRecord.getBorrowRecordNo());

        System.out.println("远程调用 发送数据: borrowSyncRecordVo = " + borrowSyncRecordVo);
        // 返回结果是 Result
        Result<BaseResult> resultResult = tradeLogApi.syncBorrowRecord(borrowSyncRecordVo);
        BaseResult baseResult = resultResult.getData();

        // 03 拿到调用结果 (把borrowRecord status修改1 和  borrow_status 进行状态修改);
        log.info("远程调用银行返回的结果是:", baseResult);
        boolean flag = true; // 模拟成功了
        if (StringUtils.hasText(baseResult.getRespMsg()) && baseResult.getRespMsg().equals("成功")) {
            borrowRecord.setStatus(true);  // 可以状态
            borrowRecord.setBorrowStatus("SYNC"); // 数据同步状态
            updateById(borrowRecord);
        }
        return "借款审核结束....";
    }


    @Override
    public Pages<BorrowRecordVo> queryBorrowRecord(
            Integer pageNum, Integer pageSize, BorrowRecordQuery borrowRecordQuery) {
        // 分页查询
        // 01 组装分页数据
        IPage<BorrowRecord> page = new Page<>();

        // 02 条件查询
        LambdaQueryWrapper<BorrowRecord> borrowRecordLambdaQuery = Wrappers.lambdaQuery(BorrowRecord.class);

        // 借款期限的范围查询
        borrowRecordLambdaQuery.between(
                !Objects.isNull(borrowRecordQuery.getStartPeriod()),
                BorrowRecord::getPeriod,
                borrowRecordQuery.getStartPeriod(),
                borrowRecordQuery.getEndPeriod());

        // 条件是否是 and 或者or 需要问项目经理   这里为了方便演示 统一使用or
        borrowRecordLambdaQuery.or();

        // 借款状态查询
        borrowRecordLambdaQuery.eq(
                !StringUtils.isEmpty(borrowRecordQuery.getBorrowStatus()),
                BorrowRecord::getBorrowStatus,
                borrowRecordQuery.getBorrowStatus());

        borrowRecordLambdaQuery.or();

        // 借款名称查询  模糊查询
        borrowRecordLambdaQuery.like(
                !StringUtils.isEmpty(borrowRecordQuery.getName()),
                BorrowRecord::getName,
                borrowRecordQuery.getName()
        );

        IPage<BorrowRecord> p = page(page, borrowRecordLambdaQuery);

        // 03 返回 分页查询需要的封装数据
        Pages<BorrowRecordVo> pages = new Pages<>();

        List<BorrowRecord> records = p.getRecords();
        // hutool bean的copy工具
        List<BorrowRecordVo> borrowRecordVos = BeanUtil.copyToList(records, BorrowRecordVo.class);

        pages.setList(borrowRecordVos);
        pages.setPageNum((int) p.getCurrent());
        pages.setPageSize((int) p.getPages());
        pages.setTotal(p.getTotal());

        return pages;
    }


    @Override
    public void addBorrowRecord(BorrowRecordDTO borrowRecordDTO) {
        // 从token中获取登录用户信息
        String userId = TokenUtils.getHeaderUserId();
        System.out.println("userId = " + userId);

        // Result<UserInfoVo> infoVoResult = userApi.findById(Long.valueOf(userId));
        // UserInfoVo userInfoVo = infoVoResult.getData();
        // System.out.println("userInfoVo = " + userInfoVo);

        // 创建对象
        BorrowRecord borrowRecord = new BorrowRecord();
        // 设置用户id
        borrowRecord.setUserId(Long.valueOf(userId));
        // 设置借款期限、借款金额
        borrowRecord.setPeriod(borrowRecordDTO.getPeriod());
        borrowRecord.setAmount(borrowRecordDTO.getAmount());
        // 设置借款编号，	"BO_"
        borrowRecord.setBorrowRecordNo("BO_" + UUID.randomUUID().toString().substring(0, 10));
        // borrowRecord.setBorrowRecordNo(
        // UniqueIDGenerator.generator(UserConstant.BORROW_CODE_PREFIX));

        // 远程调用系统管理微服务：根据用户id查询获取用户编码、用户名、身份证号码
        Result<UserInfoVo> userResult = userApi.findById(borrowRecord.getUserId());
        // 断言判断
        Assert.error(
                userResult == null || userResult.getCode() != ResultCode.SUCCESS.getCode(),
                ResultCode.DATA_IS_WRONG);
        // 获取返回结果
        UserInfoVo userInfoVo = userResult.getData();
        // 设置用户编码、借款名称 (如：许敏女士第1次借款)
        Assert.error(userInfoVo.getUserCode() == null, ResultCode.DATA_IS_WRONG);
        borrowRecord.setUserCode(userInfoVo.getUserCode());
        borrowRecord.setName(covertName(userInfoVo));

        // 各种利率 （先先死，应该放到配置文件中）
        borrowRecord.setInvestRate(new BigDecimal("10"));
        borrowRecord.setBorrowerRate(new BigDecimal("10"));
        borrowRecord.setCommissionRate(new BigDecimal("10"));
        // 还款方式：等额本金（DEBJ）、等额本息（DEBX）
        // "DEBX", "等额本息" /"DEBJ", "等额本金"  /"ALL", 一次性还款（含本息）  / "XXHB", "先息后本"
        borrowRecord.setRepaymentWay("DEBX");
        // borrowRecord.setRepaymentWay(PayTypeEnums.DEBX.getCode());
        // 借款状态：新建
        borrowRecord.setBorrowStatus("NEW");
        // borrowRecord.setBorrowStatus(BorrowStatusEnums.NEW.getCode());

        borrowRecord.setCreateDate(new Date());
        borrowRecord.setModifyDate(new Date());
        borrowRecord.setStatus(false);
        borrowRecord.setDescription("无");

        this.save(borrowRecord);
        log.info("保存借款记录成功：{}", borrowRecord);
    }


    /**
     * 处理借款名称 (如：许敏女士第1次借款)
     *
     * @param userInfoVo
     * @return
     */
    private String covertName(UserInfoVo userInfoVo) {
        // 根据用户编码（唯一）查询用户借款次数
        long count = this.count(
                Wrappers.lambdaQuery(BorrowRecord.class)
                        .eq(BorrowRecord::getUserCode, userInfoVo.getUserCode()));

        StringBuffer sb = new StringBuffer();
        sb.append(userInfoVo.getUserName());
        sb.append(getGender(userInfoVo.getIdentityCode()));
        sb.append("第" + (count + 1));
        sb.append("次借款");
        return sb.toString();
    }

    /**
     * 根据身份证号码返回性别：先生、女士
     */
    private String getGender(String identityCode) {
        // 判断身份证号码必须是18位
        Assert.error(
                identityCode == null || identityCode.length() != 18,
                ResultCode.DATA_IS_WRONG);
        // 截取
        Integer n = Integer.parseInt(identityCode.substring(16, 17));
        return n % 2 == 0 ? "女士" : "先生";
    }

}
